#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /*
        1.单向通信：客户端发送信息给服务器
    */
    //设置标题
    this->setWindowTitle("我是tcp服务器");

    //初始化服务器对象
    tcpserver=new QTcpServer(this);

    //绑定并监听
    tcpserver->listen(QHostAddress("192.168.6.1"),10000);

    //主动关联newConnection信号
    connect(tcpserver,SIGNAL(newConnection()),this,SLOT(newClientLink()));
}

MainWindow::~MainWindow()
{
    //关闭套接字
    tcpsock->close();
    delete ui;
}
//新的客户端连接
void MainWindow::newClientLink()
{
    //立马产生新的套接字
    tcpsock=tcpserver->nextPendingConnection();

    //把目前连接成功的那个客户端套接字存放到容器中
    socklist.push_back(tcpsock);

    //把目前连接成功的那个客户端ip和端口号获取
    QString ip=tcpsock->peerAddress().toString();
    quint16 port=tcpsock->peerPort();
    //在横向列表框显示出来
    QString msg=QString("%1@%2").arg(ip).arg(port);
    ui->listWidget->addItem(msg);

    //接收客户端的信息
    //错误示范：不可以直接调用readAll/read接收对方的信息
    //QByteArray buf=tcpsock->readAll();
    //在文本浏览框显示
    //ui->textBrowser->setText(buf);

    //关联readyRead()信号，在槽函数里面接收客户端的信息
    connect(tcpsock,SIGNAL(readyRead()),this,SLOT(recvClientMsg()));

    //关联disconnected()信号，在槽函数里面处理客户端断开之后的逻辑功能
    connect(tcpsock,SIGNAL(disconnected()),this,SLOT(clientUnlink()));
}
//专门接收客户端信息的槽函数
void MainWindow::recvClientMsg()
{
    //获取信号的发送者
    QObject *p=sender();
    //把QObject转成子类QTcpSocket
    QTcpSocket *cursock=qobject_cast<QTcpSocket *>(p);

    //获取给我发送信息的那个客户端ip和端口号
    QString ip=cursock->peerAddress().toString();
    quint16 port=cursock->peerPort();

    //接收信息
    QByteArray buf=cursock->readAll();
    //在文本浏览框显示
    //ui->textBrowser->setText(buf); //会覆盖原来的内容
    QString str(buf);
    QString msg=QString("%1@%2给我发送:%3").arg(ip).arg(port).arg(str);
    ui->textBrowser->append(msg); //追加显示，不会覆盖原来的内容
}

//发送信息给客户端
void MainWindow::on_pushButton_clicked()
{
    //获取文本编辑框输入的内容
    QString msg=ui->textEdit->toPlainText();
    //发给客户端
    //遍历容器找到对应的套接字
    int i;
    for(i=0; i<socklist.size(); i++)
    {
        QString ip=socklist.at(i)->peerAddress().toString();
        quint16 port=socklist.at(i)->peerPort();
        QString msg=QString("%1@%2").arg(ip).arg(port);
        //比较你双击跟当前x的是不是一样
        if(msg==curclientmsg)
            break;
    }
    socklist.at(i)->write(msg.toUtf8());
}
//双击横向列表框
void MainWindow::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
    //获取你双击的那个客户端ip和端口号
    curclientmsg=item->text();
}
//处理客户端断开的槽函数
void MainWindow::clientUnlink()
{
    //获取信号的发送者
    QObject *p=sender();
    //把QObject转成子类QTcpSocket
    QTcpSocket *cursock=qobject_cast<QTcpSocket *>(p);

    //获取断开连接那个客户端ip和端口号
    QString ip=cursock->peerAddress().toString();
    quint16 port=cursock->peerPort();
    QString msg=QString("%1@%2客户端断开了").arg(ip).arg(port);
    //qDebug()<<msg;
    QMessageBox::warning(this,"断开了",msg);
}
